// Copyright (c) 2024 CHANGLEI. All rights reserved.

import 'package:charts_grasp/src/chart/chart_segment/chart_segment.dart';
import 'package:charts_grasp/src/chart/chart_series/series.dart';
import 'package:charts_grasp/src/chart/common/common.dart';
import 'package:charts_grasp/src/chart/common/renderer.dart';
import 'package:charts_grasp/src/chart/common/segment_properties.dart';
import 'package:charts_grasp/src/chart/utils/helper.dart';
import 'package:flutter/material.dart';

class AreaSegment extends ChartSegment {
  late SegmentProperties _segmentProperties;
  bool _isInitialize = false;

  @override
  Paint getFillPaint() {
    _setSegmentProperties();
    fillPaint = Paint();
    if (_segmentProperties.series.gradient == null) {
      if (_segmentProperties.color != null) {
        fillPaint!.color = _segmentProperties.color!;
        fillPaint!.style = PaintingStyle.fill;
      }
    } else {
      fillPaint = (_segmentProperties.pathRect != null)
          ? getLinearGradientPaint(
              _segmentProperties.series.gradient!,
              _segmentProperties.pathRect!,
              SeriesHelper.getSeriesRendererDetails(_segmentProperties.seriesRenderer)
                  .stateProperties
                  .requireInvertedAxis,)
          : fillPaint;
    }
    assert(_segmentProperties.series.opacity >= 0 == true,
        'The opacity value of the area series should be greater than or equal to 0.',);
    assert(_segmentProperties.series.opacity <= 1 == true,
        'The opacity value of the area series should be less than or equal to 1.',);
    fillPaint!.color = (_segmentProperties.series.opacity < 1 == true && fillPaint!.color != Colors.transparent)
        ? fillPaint!.color.withOpacity(_segmentProperties.series.opacity)
        : fillPaint!.color;
    _segmentProperties.defaultFillColor = fillPaint;
    setShader(_segmentProperties, fillPaint!);
    return fillPaint!;
  }

  @override
  Paint getStrokePaint() {
    _setSegmentProperties();
    final Paint strokePaint = Paint();
    strokePaint
      ..style = PaintingStyle.stroke
      ..strokeWidth = _segmentProperties.series.borderWidth;
    if (_segmentProperties.series.borderGradient != null) {
      strokePaint.shader =
          _segmentProperties.series.borderGradient!.createShader(_segmentProperties.strokePath!.getBounds());
    } else if (_segmentProperties.strokeColor != null) {
      strokePaint.color = _segmentProperties.series.borderColor;
    }
    _segmentProperties.series.borderWidth == 0 ? strokePaint.color = Colors.transparent : strokePaint.color;
    strokePaint.strokeCap = StrokeCap.round;
    _segmentProperties.defaultStrokeColor = strokePaint;
    return strokePaint;
  }

  @override
  void calculateSegmentPoints() {}

  @override
  void onPaint(Canvas canvas) {
    _setSegmentProperties();
    _segmentProperties.pathRect = _segmentProperties.path.getBounds();
    canvas.drawPath(
        _segmentProperties.path, (_segmentProperties.series.gradient == null) ? fillPaint! : getFillPaint(),);
    if (strokePaint!.color != Colors.transparent && _segmentProperties.strokePath != null) {
      drawDashedLine(canvas, _segmentProperties.series.dashArray, strokePaint!, _segmentProperties.strokePath!);
    }
  }

  void _setSegmentProperties() {
    if (!_isInitialize) {
      _segmentProperties = SegmentHelper.getSegmentProperties(this);
      _isInitialize = true;
    }
  }
}
